﻿using System.Collections.Generic;

namespace Zinnia.Caching.Imp
{
    /// <summary>
    /// 信号器
    /// </summary>
    public class Signals : ISignals
    {
        /// <summary>
        /// 令牌字典
        /// </summary>
        readonly IDictionary<object, Token> _tokens = new Dictionary<object, Token>();
        public void Trigger<T>(T signal)
        {
            lock (_tokens)
            {
                //尝试从令牌字典中根据信号器来搜索相应的令牌，如果令牌存在则触发，并从字典中移除令牌，不存在则忽略
                Token token;
                if (_tokens.TryGetValue(signal, out token))
                {
                    _tokens.Remove(signal);
                    token.Trigger();
                }
            }
        }

        public IVolatileToken When<T>(T signal)
        {
            lock (_tokens)
            {
                //先从字典中查找令牌，如果令牌存在则返回，如果不存在，则新建一个并存入字典中
                Token token;
                if (!_tokens.TryGetValue(signal, out token))
                {
                    token = new Token();
                    _tokens[signal] = token;
                }
                return token;
            }
        }
        /// <summary>
        /// 令牌
        /// </summary>
        class Token : IVolatileToken
        {
            public Token()
            {
                IsCurrent = true;
            }
            /// <summary>
            /// 默认为true,被信号器触发之后为false
            /// </summary>
            public bool IsCurrent { get; private set; }
            public void Trigger() { IsCurrent = false; }
        }
    }
}
